﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using ARchGL.Platform.Configuration;
using ARchGL.Platform.Core;
using ARchGL.Platform.Dtos;
using ARchGL.Platform.Juneng;
using ARchGL.Platform.Utils;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ARchGL.Platform.Application
{
    /// <summary>
    /// 系统服务 实现
    /// </summary>
    public class SystemsAppService : PlatformAppServiceBase, ISystemsAppService
    {
        private readonly IConfigurationRoot appConfiguration;
        private readonly IRepository<AppVersions, Guid> appVersionsRepository;

        public SystemsAppService(
            IHostingEnvironment env,
            IRepository<AppVersions, Guid> _appVersionsRepository)
        {
            appConfiguration = env.GetAppConfiguration();
            appVersionsRepository = _appVersionsRepository;
        }

        #region 版本信息

        /// <summary>
        /// 新建版本信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize]
        public async Task<Guid> CreateVersion(AppVersionDto input)
        {
            var entity = ObjectMapper.Map<AppVersions>(input);
            entity.CreatorUserId = UserManager.PrimaryId;
            return await appVersionsRepository.InsertAndGetIdAsync(entity);
        }

        /// <summary>
        /// 更新下载次数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task UpdateVersionCount(Guid input)
        {
            var entity = await appVersionsRepository.FirstOrDefaultAsync(input);
            if (entity == null) return;
            entity.Count++;
            await appVersionsRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 获取最后版本信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<AppVersionDto> QueryLastVersion(AppVersionsInput input)
        {
            var entity = await appVersionsRepository.GetAll().WhereIf(input.Type > 0, x => x.Type == input.Type).OrderByDescending(x => x.UpdateTime).FirstOrDefaultAsync();
            return ObjectMapper.Map<AppVersionDto>(entity);
        }

        /// <summary>
        /// 获取版本信息-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<AppVersionDto>> QueryVersionsPagedList(AppVersionsInput input)
        {
            var query = appVersionsRepository.GetAll()
                .WhereIf(input.Type > 0, x => x.Type == input.Type)
                .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Version.Contains(input.Filter) || x.Content.Contains(input.Filter) || x.NextContent.Contains(input.Filter));

            var items = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);
            var result = ObjectMapper.Map<List<AppVersionDto>>(items.ToList());

            return new PagedResultDto<AppVersionDto>(query.Count(), result);
        }

        #endregion

        #region 访问签名

        /// <summary>获取文件访问签名</summary>
        [AbpAuthorize]
        public async Task<string> QueryParameter()
        {
            var appId = appConfiguration["FileAccessSignature:appId"];
            var secretId = appConfiguration["FileAccessSignature:secretId"];
            var secreteKey = appConfiguration["FileAccessSignature:secreteKey"];
            var ticks = Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds);

            return await Task.FromResult($"a={appId}&t={ticks}&at={DetectionSignature(appId, secretId, secreteKey, ticks)}");
        }

        private static string DetectionSignature(string appId, string secretId, string secretKey, double ticks)
        {
            var plainText = $"a={appId}&s={secretId}&t={ticks}";
            using (var mac = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey)))
            {
                var hash = mac.ComputeHash(Encoding.UTF8.GetBytes(plainText));
                var pText = Encoding.UTF8.GetBytes(plainText);
                var all = new byte[hash.Length + pText.Length];
                Array.Copy(hash, 0, all, 0, hash.Length);
                Array.Copy(pText, 0, all, hash.Length, pText.Length);
                return Convert.ToBase64String(all);
            }
        }

        #endregion

        /// <summary>
        /// 获取心跳
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<object> GetHeartbeat(AppVersionDto input)
        {
            var entity = ObjectMapper.Map<AppVersions>(input);
            entity.CreatorUserId = UserManager.PrimaryId;
            return new int[]
            {
            };
        }
    }
}
